﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TaskManager
{
    class Tool
    {
        #region 文件读取与保存

        /// <summary>
        /// 获取文件中的数据串
        /// </summary>
        public static string fileToString(String filePath)
        {
            string str = "";

            //获取文件内容
            if (System.IO.File.Exists(filePath))
            {
                System.IO.StreamReader file1 = new System.IO.StreamReader(filePath);//读取文件中的数据
                str = file1.ReadToEnd();                                            //读取文件中的全部数据

                file1.Close();
                file1.Dispose();
            }
            return str;
        }

        /// <summary>
        /// 保存数据data到文件处理过程，返回值为保存的文件名
        /// </summary>
        public static String SaveProcess(String data, String name)
        {
            string CurDir = System.AppDomain.CurrentDomain.BaseDirectory + @"SaveDir\";    //设置当前目录
            if (!System.IO.Directory.Exists(CurDir)) System.IO.Directory.CreateDirectory(CurDir);   //该路径不存在时，在当前文件目录下创建文件夹"导出.."

            //不存在该文件时先创建
            String filePath = CurDir + name + ".txt";
            System.IO.StreamWriter file1 = new System.IO.StreamWriter(filePath, false);     //文件已覆盖方式添加内容

            file1.Write(data);                                                              //保存数据到文件

            file1.Close();                                                                  //关闭文件
            file1.Dispose();                                                                //释放对象

            return filePath;
        }

        /// <summary>
        /// 获取应用的当前工作路径
        /// </summary>
        public static String curDir()
        {
            string CurDir = System.AppDomain.CurrentDomain.BaseDirectory;
            return CurDir;
        }

        /// <summary>
        /// 检测目录是否存在，若不存在则创建
        /// </summary>
        public static void confirmDir(string path)
        {
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
        }

        /// <summary>
        /// 保存数据data到文件处理过程，返回值为保存的文件名
        /// </summary>
        public static String SaveFile(String data, String filePath)
        {
            //string CurDir = System.AppDomain.CurrentDomain.BaseDirectory + @"SaveDir\";    //设置当前目录
            //if (!System.IO.Directory.Exists(CurDir)) System.IO.Directory.CreateDirectory(CurDir);   //该路径不存在时，在当前文件目录下创建文件夹"导出.."

            ////不存在该文件时先创建
            //String filePath = CurDir + name + ".txt";
            System.IO.StreamWriter file1 = new System.IO.StreamWriter(filePath, false);     //文件已覆盖方式添加内容
            file1.Write(data);                                                              //保存数据到文件

            file1.Close();                                                                  //关闭文件
            file1.Dispose();                                                                //释放对象

            return filePath;
        }

        #endregion



        #region xml、html节点数据解析

        /// <summary>
        /// 获取指定串值对的数据, start = <tbody>, end = </tbody>
        /// </summary>
        public static string subString(string data, string start, string end)
        {
            try
            {
                int i1 = data.IndexOf(start) + start.Length, i2 = data.IndexOf(end, i1);
                string tmp = data.Substring(i1, i2 - i1);

                return tmp;
            }
            catch (Exception) { return null; }
        }

        /// <summary>
        /// 获取指定串值对的数据, 从开始寻找start = <tbody>, 从结尾寻找end = </tbody>
        /// </summary>
        public static string subStringE(string data, string start, string end)
        {
            try
            {
                int i1 = data.IndexOf(start) + start.Length, i2 = data.LastIndexOf(end);
                string tmp = data.Substring(i1, i2 - i1);

                return tmp;
            }
            catch (Exception) { return null; }
        }

        /// <summary>
        /// 获取节点的数据, node为节点名称
        /// </summary>
        public static string getNode(string data, string nodeName)
        {
            try
            {
                data = subString(data, "<" + nodeName, "/" + nodeName + ">");
                data = subStringE(data, ">", "<");

                return data.Trim();     // 去除首位空格
            }
            catch (Exception) { return null; }
        }

        /// <summary>
        /// 获取节点对应的所有节点数据, node为节点名称
        /// </summary>
        public static List<string> getNodes(string data, string nodeName)
        {
            List<string> Nodes = new List<string>();

            try
            {
                int pos = 0;
                while (pos != -1)
                {
                    string tmp = getNode(data, nodeName);// 获取第一个节点数据
                    if (tmp == null) break;
                    Nodes.Add(tmp);

                    string end = "/" + nodeName + ">";
                    pos = data.IndexOf(end) + end.Length;// 记录当前解析的最后位置
                    data = data.Substring(pos);          // 删除已解析部分
                }
            }
            catch (Exception) { }
            return Nodes;

        }

        /// <summary>
        /// 从节点node中提取子节点nodeName中的数据，无此子节点则原样返回
        /// </summary>
        public static string trimNode(string node, string[] nodeName)
        {
            string tmp = node;
            foreach (string name in nodeName) if (tmp.Contains("<" + name)) tmp = Tool.getNode(tmp, name);
            return tmp;
        }

        /// <summary>
        /// 从节点数组nodes中提取子节点nodeName中的数据，无此子节点则原样返回
        /// </summary>
        public static List<string> getTrimNodes(List<string> nodes, string[] nodeName)
        {
            List<string> Nodes = new List<string>();
            foreach (string node in nodes) Nodes.Add(trimNode(node, nodeName));
            return Nodes;
        }

        #endregion


        # region 注册表操作
        //设置软件开机启动项： RegistrySave(@"Microsoft\Windows\CurrentVersion\Run", "QQ", "C:\\windows\\system32\\QQ.exe");  

        /// <summary>
        /// 记录键值数据到注册表subkey = @"Scimence\Email\Set";
        /// </summary>
        public static void RegistrySave(string subkey, string name, object value)
        {
            //设置一个具有写权限的键 访问键注册表"HKEY_CURRENT_USER\Software"
            Microsoft.Win32.RegistryKey keyCur = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software", true);
            Microsoft.Win32.RegistryKey keySet = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\" + subkey, true);
            if (keySet == null) keySet = keyCur.CreateSubKey(subkey);   //键不存在时创建

            keySet.SetValue(name, value);   //保存键值数据
        }

        /// <summary>
        /// 获取注册表subkey下键name的字符串值
        /// <summary>
        public static string RegistryStrValue(string subkey, string name)
        {
            object value = RegistryValue(subkey, name);
            return value == null ? "" : value.ToString();
        }

        /// <summary>
        /// 获取注册表subkey下键name的值
        /// <summary>
        public static object RegistryValue(string subkey, string name)
        {
            Microsoft.Win32.RegistryKey keySet = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\" + subkey, true);
            return (keySet == null ? null : keySet.GetValue(name, null));
        }

        /// <summary>
        /// 判断注册表是否含有子键subkey
        /// <summary>
        public static bool RegistryCotains(string subkey)
        {
            Microsoft.Win32.RegistryKey keySet = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\" + subkey, true);
            return (keySet != null);
        }

        /// <summary>
        /// 判断注册表subkey下是否含有name键值信息
        /// <summary>
        public static bool RegistryCotains(string subkey, string name)
        {
            //设置一个具有写权限的键 访问键注册表"HKEY_CURRENT_USER\Software"
            Microsoft.Win32.RegistryKey keySet = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\" + subkey, true);

            if (keySet == null) return false;
            else return keySet.GetValueNames().Contains<string>(name);
        }

        /// <summary>
        /// 删除注册表subkey信息
        /// <summary>
        public static void RegistryRemove(string subkey)
        {
            //设置一个具有写权限的键 访问键注册表"HKEY_CURRENT_USER\Software"
            Microsoft.Win32.RegistryKey keyCur = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software", true);
            Microsoft.Win32.RegistryKey keySet = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\" + subkey, true);

            if (keySet != null) keyCur.DeleteSubKeyTree(subkey);      //删除注册表信息
        }

        /// <summary>
        /// 删除注册表subkey下的name键值信息
        /// <summary>
        public static void RegistryRemove(string subkey, string name)
        {
            //设置一个具有写权限的键 访问键注册表"HKEY_CURRENT_USER\Software"
            Microsoft.Win32.RegistryKey keySet = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\" + subkey, true);
            if (keySet != null) keySet.DeleteValue(name, false);
        }

        # endregion

        /// <summary>
        ///  设置ListView列表显示信息
        /// </summary>
        public static void setData(ListView list, List<string> heads, List<string[]> rows, bool simpleMode)
        {
            //list.View = View.Details;
            //list.ShowGroups = true;

            //list.HeaderStyle = ColumnHeaderStyle.Nonclickable;
            //list.FullRowSelect = true;

            list.BeginUpdate();

            list.Items.Clear();
            list.Groups.Clear();
            list.Columns.Clear();

            // 添加标题
            for (int i = 0; i < heads.Count; i++)
            {
                int width = ListColumnWidth(heads[i], simpleMode);
                list.Columns.Add(heads[i], width, simpleMode ? HorizontalAlignment.Left : HorizontalAlignment.Center);
            }

            // 分组
            list.Groups.Add(new ListViewGroup("已逾期", HorizontalAlignment.Left));    // 逾期未完成
            list.Groups.Add(new ListViewGroup("今日截止", HorizontalAlignment.Left));  // 今日截止，且未完成
            list.Groups.Add(new ListViewGroup("未完成", HorizontalAlignment.Left));    // 其他未完成
            list.Groups.Add(new ListViewGroup("已结束", HorizontalAlignment.Left));
            int G0 = 0, G1 = 1, G2 = 2, G3 = 3;        //分组索引值

            int stateIndex = heads.IndexOf("状态");    //获取状态所在的列位置
            if (stateIndex == -1) stateIndex = heads.IndexOf("方案");

            int finalDateIndex = heads.IndexOf("截止");//任务截至日期

            string date = Tool.getDate(DateTime.Now);  // 获取当前日期

            // 添加信息到列表,并分组
            foreach (string[] row in rows)
            {
                string state = row[stateIndex].Trim();
                string finalDate = finalDateIndex == -1 ? "" : row[finalDateIndex].Trim();  // 获取截止日期
                int dateCmp = cmp(date, finalDate);             // 当前日期与截止日期的比较结果

                // 按任务的状态和截止日期，设置各行的显示颜色
                ListViewItem Iteam = new ListViewItem(row);
                if (state.Equals("进行中")) Iteam.ForeColor = getColor(dateCmp);
                else Iteam.ForeColor = getColor(state);

                list.Items.Add(Iteam);

                // 按任务状态进行分组：逾期未完成、今日截止、其他未完成，已完成
                Boolean finish = (state.Equals("已完成") || state.Equals("已关闭") || state.Equals("已取消") || state.Equals("已解决"));
                if (finish)                                                 // 已结束
                    list.Groups[G3].Items.Add(Iteam);
                else if (state.Equals("未开始") || state.Equals("已暂停"))  // 普通未完成
                    list.Groups[G2].Items.Add(Iteam);
                else if (state.Equals("进行中") || state.Equals(""))
                {
                    if (dateCmp > 0) list.Groups[G0].Items.Add(Iteam);       // 逾期未完成
                    else if (dateCmp == 0) list.Groups[G1].Items.Add(Iteam); // 今日截止
                    else list.Groups[G2].Items.Add(Iteam);                   // 普通未完成
                }
            }

            list.EndUpdate();
        }

        // 返回date1与date2的比较结果，日期需为 "yyyy-MM-dd"格式
        private static int cmp(string date1, string date2)
        {
            date1 = date1.Replace("-", "");
            date2 = date2.Replace("-", "");

            int n1 = date1.Equals("") ? 0 : Int32.Parse(date1);
            int n2 = date2.Equals("") ? 99999999 : Int32.Parse(date2);
            n2 = AIDateCheck(n1, n2);   // 日期n2校验

            return n1 - n2;
        }

        // 对日期n2进行校验，转换为年月日格式：20151225
        private static int AIDateCheck(int n1, int n2)
        {
            if (n2 > 10000) return n2;
            else
            {
                int n1_Y = n1 / 10000, n1_MD = n1 % 10000;  // 取年、月日值
                int gap = n1_MD - n2;
                if (gap > 600 || gap<-600)
                    n2 = (n1_Y + (gap > 0 ? 1 : -1)) * 10000 + n2;           // 20151231 - 0630 = 20150601   (20151231_20160630之间差值大于600，属于2016年)
                else n2 = n1_Y * 10000 + n2;                // 差值小于等于600，记为当前年份

                return n2;
            }
        }

        // 根据任务的状态，为其设置不同的颜色 dateCmp为日期比较结果
        private static Color getColor(int dateCmp)
        {
            if (dateCmp > 0) return Color.LightPink;            // 已逾期
            else if (dateCmp == 0) return Color.HotPink;  // 今日未完成
            else return Color.Orange;                     // 其他未完成
        }


        // 从给定的任务信息中提取所需信息（id, 任务名，状态）
        public static List<string[]> getTaskInfo(List<string> heads, List<string[]> rows)
        {
            List<string[]> list = new List<string[]>();

            int nameIndex = heads.IndexOf("任务名称");
            if (nameIndex == -1) nameIndex = heads.IndexOf("Bug标题");

            int stateIndex = heads.IndexOf("状态");    //获取状态所在的列位置
            if (stateIndex == -1) stateIndex = heads.IndexOf("方案");

            // 提取所需信息
            foreach (string[] row in rows)
            {
                string[] dataRow = new string[] { row[0].Trim(), row[nameIndex].Trim(), row[stateIndex].Trim() };
                list.Add(dataRow);
            }

            return list;
        }

        // 根据任务的状态，为其设置不同的颜色
        public static Color getColor(string state)
        {
            Color C = Color.Black;

            if (state.Equals("未开始")) C = Color.LightGray;
            else if (state.Equals("（NEW）")) C = Color.Red;
            else if (state.Equals("进行中")) C = Color.LightPink;
            else if (state.Equals("已完成")) C = Color.LightGreen;
            else if (state.Equals("已暂停")) C = Color.LightGray;
            else if (state.Equals("已取消")) C = Color.Black;
            else if (state.Equals("已关闭")) C = Color.LightBlue;
            else if (state.Equals("已解决")) C = Color.LightGreen;

            else if (state.Equals("完成")) C = Color.LightGreen;
            else if (state.Equals("提前")) C = Color.LightGreen;
            else if (state.Equals("超时")) C = Color.LightPink;
            else if (state.Equals("（超时）")) C = Color.Red;
            else if (state.Equals("（将到期）")) C = Color.Red;

            else if (state.Equals("开发中")) C = Color.LightPink;
            else if (state.Equals("测试中")) C = Color.LightPink;
            else if (state.Equals("已激活")) C = Color.LightPink;
            else if (state.Equals("已变动")) C = Color.LightPink;
            else if (state.Equals("已起草")) C = Color.LightPink;
            else if (state.Equals("blocked")) C = Color.LightPink;

            else if (state.Equals("已计划")) C = Color.LightGray;
            else if (state.Equals("已立项")) C = Color.LightPink;
            else if (state.Equals("开发完成")) C = Color.LightGreen;
            else if (state.Equals("已测试")) C = Color.LightPink;
            else if (state.Equals("已验收")) C = Color.LightGreen;
            else if (state.Equals("已发布")) C = Color.Black;

            return C;
        }

        // 获取状态类型为中文
        public static string toCN(string status)
        {
            //if (status.Contains("wait")) return "未开始";
            if (status.Contains("wait")) return "（NEW）";
            else if (status.Contains("doing")) return "进行中";
            else if (status.Contains("done")) return "已完成";
            else if (status.Contains("pause")) return "已暂停";
            else if (status.Contains("cancel")) return "已取消";
            else if (status.Contains("closed")) return "已关闭";

            else if (status.Contains("planned")) return "已计划";
            else if (status.Contains("projected")) return "已立项";
            else if (status.Contains("developing")) return "开发中";
            else if (status.Contains("developed")) return "开发完成";
            else if (status.Contains("testing")) return "测试中";
            else if (status.Contains("tested")) return "已测试";
            else if (status.Contains("verified")) return "已验收";
            else if (status.Contains("released")) return "已发布";

            else if (status.Contains("active")) return "已激活";
            else if (status.Contains("resolved")) return "已解决";

            else if (status.Contains("blocked")) return "blocked";
            else if (status.Contains("changed")) return "已变动";
            else if (status.Contains("draft")) return "已起草";


            else if (status.Contains("0")) return "完成";
            else if (status.Contains("1")) return "提前";
            else if (status.Contains("2")) return "超时";
            else if (status.Contains("3")) return "进行中";

            return "其它";
        }

        // 根据任务的状态，设置是否置顶显示,仅进行中、未开始的置顶显示
        public static bool getUnFinished(string state)
        {
            return !(state.Equals("进行中") || state.Equals("未开始") || state.Equals("（NEW）") || state.Equals("（超时）") || state.Equals("（将到期）"));
        }

        // 设置ListView各列的宽度
        private static int ListColumnWidth(int index)
        {
            int[] W = { 40, 20, 100, 180 };
            if (0 <= index && index < W.Length) return W[index];
            else return 60;
        }

        private static string[] headNames = { "ID", "P", "所属项目", "任务名称", "创建", "指派给", "由谁完成", "预", "消耗", "剩", "截止", "状态", "操作", "所属产品", "需求名称", "所属计划", "预计", "阶段", "审核者", "Bug标题", "方案" };
        private static int[] headWidths = { 40, 40, 170, 320, 60, 60, 60, 40, 40, 40, 80, 60, 40, 170, 320, 170, 60, 60, 120, 320, 60 };
        private static List<string> heads = headNames.ToList<string>();

        // 根据列名称，设置ListView各列的宽度
        private static int ListColumnWidth(string head, bool simpleMode)
        {
            if (simpleMode)    // 精简模式时，仅显示任务名称和状态
            {
                if (head.Equals("任务名称") || head.Equals("状态") || head.Equals("Bug标题") || head.Equals("方案"))
                    return headWidths[heads.IndexOf(head)];
                else return 0;
            }
            else
            {
                if (heads.Contains(head))
                    return headWidths[heads.IndexOf(head)];
                else return 60;
            }
        }

        // 从特定格式的列表数据data中提取列标题， 数据示例：String data = Tool.fileToString("D:\\tmp1\\1.html");
        public static List<string> getHeads(string data)
        {
            // 获取列表标题
            string thead = Tool.getNode(data, "thead");
            thead = Tool.getNode(thead, "tr");
            List<string> ths = Tool.getNodes(thead, "th");

            ths = Tool.getTrimNodes(ths, new string[] { "div", "a" });

            return ths;
        }

        // 从特定格式的列表数据data中提取列各列表项数据
        public static List<string[]> getBodys(string data)
        {
            // 获取列表项信息
            string tbody = Tool.getNode(data, "tbody");
            List<string> rows = Tool.getNodes(tbody, "tr");     // 解析行信息

            List<string[]> tds = new List<string[]>();          // 解析所有列表项信息
            foreach (string tmp in rows)
            {
                List<string> iteams = Tool.getNodes(tmp, "td");
                iteams = Tool.getTrimNodes(iteams, new string[] { "div", "a", "i", "span" });
                tds.Add(iteams.ToArray());
            }

            return tds;
        }


        // 将字符串n转换为数值
        public static int toInt(String n, int defaultN = 0)
        {
            try { return int.Parse(n); }
            catch (Exception) { return defaultN; }
        }

        // 将字符串n转换为数值
        public static float toFloat(String n, float defaultN)
        {
            try { return float.Parse(n); }
            catch (Exception) { return defaultN; }
        }

        // 将字符串n转换为数值
        public static float toFloat(String n)
        {
            return toFloat(n, 0);
        }



        # region 日期时间处理逻辑

        // 将n转化为2位符号数， 0-99 转化为00-99
        public static string TwoChar(int n)
        {
            return (n < 10 ? "0" : "") + n;
        }

        // 获取DateTime的日期部分：2005-06-07
        public static string getDate(DateTime T)
        {
            return T.Year + "-" + TwoChar(T.Month) + "-" + TwoChar(T.Day);
        }

        // 获取DateTime的时间部分：12:23:34
        public static string getTime(DateTime T)
        {
            return TwoChar(T.Hour) + ":" + TwoChar(T.Minute) + ":" + TwoChar(T.Second);
        }

        // 将DateTime日期转化为固定的日期格式： 2005-06-07 12:23:34
        public static string ToString(DateTime T)
        {
            return getDate(T) + " " + getTime(T);
            //DateTime.Now.ToString("yyyy-MM-dd  hh:mm:ss");
        }

        // 获取当前时间如： 2005-06-07 12:23:34
        public static string TimeNow()
        {
            return ToString(DateTime.Now);
        }

        // 获取相对于当前时间，days天后的日期，获取date = "2005-6-7 12:23:34"
        public static string TimeNowAdd(int days)
        {
            DateTime Now = DateTime.Now;
            Now = Now.AddDays(days);

            string Time = ToString(Now);
            return Time;                               // "2016-5-26 12:23:34"
        }

        // 根据当前日期获取 格式20160101类型的日期
        public static string DateString()
        {
            return getDate(DateTime.Now).Replace("-", "");
        }

        /// <summary>
        /// 将timeStr = 08:30:00转化为long数据 083000
        /// </summary>
        public static long formatTime(String timeStr)
        {
            int hour = 0, minute = 0, second = 0;

            try
            {
                if (timeStr != null && !timeStr.Equals(""))
                {
                    String[] A = timeStr.Split(':');
                    if (A.Length > 0) hour = Tool.toInt(A[0]);
                    if (A.Length > 1) minute = Tool.toInt(A[1]);
                    if (A.Length > 2) second = Tool.toInt(A[2]);
                }
            }
            catch (Exception ex) { }

            return (hour * 100 + minute) * 100 + second;
        }

        /// <summary>
        /// 判定当前时间是否 >= timeStr, 
        /// timeStr 形如 12:23:34
        /// </summary>
        public static bool TimeAbove(String timeStr)
        {
            bool above = false;
            try
            {   //DateTime.Now.ToString("yyyy-MM-dd  hh:mm:ss");
                string timeNowStr = Tool.getTime(DateTime.Now);     // 获取当前时间, 形如 12:23:34
                long now = Tool.formatTime(timeNowStr);             // 获取时间，形如 122334
                long target = Tool.formatTime(timeStr);             // 目标时间值
                if (now >= target) above = true;                    // 达到目标时间值
            }
            catch (Exception ex) { }

            return above;
        }

        // DateTime.Compare(time1, time2);
        // 从字符串获取日期
        //string mytime = "2005-6-7 12:23:34";
        public static DateTime parseDate(string date)
        {
            //IFormatProvider culture = new System.Globalization.CultureInfo("zh-CN", true);
            //string[] expectedFormats = { "yyyy-MM-dd HH:mm:ss", "yyyy-MM-d HH:mm:ss", "yyyy-M-dd HH:mm:ss", "yyyy-M-dd HH:mm:ss" };
            //DateTime dateTime = DateTime.ParseExact(date, expectedFormats, culture, System.Globalization.DateTimeStyles.AllowInnerWhite);

            DateTime dateTime;
            try
            {
                dateTime = DateTime.Parse(date);
            }
            catch (Exception ex) 
            {
                dateTime = new DateTime(0);
            }

            return dateTime;
        }

        // 对两个字符串日期进行比较
        public static int Date_cmp(string str1, string str2)
        {
            //DateTime date1 = Tool.parseDate("2005-6-07 12:23:34");
            //DateTime date2 = Tool.parseDate("2005-07-07 12:23:34");
            //return -1

            if (str2.Equals("0000-00-00 00:00:00")) return 1;
            DateTime date1 = Tool.parseDate(str1);
            DateTime date2 = Tool.parseDate(str2);

            return DateTime.Compare(date1, date2);
        }

        // 判定日期date是否在[date1到date2]之间，是返回true;
        public static bool DateInRegion(string date, string date1, string date2)
        {
            return (Date_cmp(date, date1) >= 0) && (Date_cmp(date, date2) <= 0);
        }

        // 判定日期date是否在(date1+minute到date1+minute+second]之间，是返回true;
        public static bool DateInRegion(string date, string date1, int minute, int second)
        {
            DateTime D = parseDate(date1).AddMinutes(minute);
            string d1 = ToString(D);
            string d2 = ToString(D.AddSeconds(second));

            return DateInRegion(date, d1, d2);
        }


        // 对两个日期date1和date2进行比较
        // date1 = 2016-05-27  date2 = 2016-05-29
        public static long Shortdate_cmp(string date1, string date2)
        {
            long d1 = long.Parse(date1.Replace("-", "").Replace("/", ""));
            long d2 = long.Parse(date2.Replace("-", "").Replace("/", ""));
            return d1 - d2;
        }

        // 获取两个日期之间的分钟差值
        public static long Sub_minite(string str1, string str2)
        {
            DateTime date1 = Tool.parseDate(str1);
            DateTime date2 = Tool.parseDate(str2);

            return (date1.Ticks - date2.Ticks) / 10000 / 1000 / 60;
        }

        // 获取某个日期的对应的毫秒值
        public static long ms(DateTime time)
        {
            return time.Ticks / 10000;
        }

        // 以日为周期，获取date = "2005-6-7 12:23:34" 对应今日时间
        public static string toTodayTime(string date)
        {
            DateTime D = parseDate(date);            // 转化date为日期
            string D_day = getDate(D);               // 获取日期 "2005-06-07"
            string T_day = getDate(DateTime.Now);    // 今日日期 "2016-05-23"

            string todayTime = ToString(D).Replace(D_day, T_day);
            return todayTime;                       // "2016-5-23 12:23:34"
        }

        // 以周为周期，获取date = "2005-6-7 12:23:34" 对应的本周日期时间
        public static string toThisWeekTime(string date)
        {
            DateTime D = parseDate(date);                       // 转化date为日期
            string T1_day = getDate(D);
            DayOfWeek DayOfWeek1 = D.DayOfWeek;                 // 获取日期为星期几

            DateTime Now = DateTime.Now;
            DayOfWeek DayOfWeek2 = Now.DayOfWeek;               // 当前为星期几
            Now = Now.AddDays(DayOfWeek1 - DayOfWeek2);
            string T2_day = getDate(Now);                       // 获取D_day的本周日期 "2016/5/24"

            string weekTime = ToString(D).Replace(T1_day, T2_day);
            return weekTime;                                   // "2016-5-26 12:23:34"
        }

        /// <summary>
        /// 判定指定的日期是否为周末
        /// </summary>
        public static bool isWeekend(DateTime date)
        {
            DayOfWeek n = date.DayOfWeek;               // 当前为星期几
            return (n == DayOfWeek.Saturday || n == DayOfWeek.Sunday);
        }

        /// <summary>
        /// 判定指定的日期是否为周末
        /// </summary>
        public static bool todayIsWeekend()
        {
            return isWeekend(DateTime.Now);
        }


        // 以月为周期，获取date = "2016-04-07 12:23:34" 对应的本月日期时间
        public static string toThisMonthTime(string date)
        {
            DateTime D = parseDate(date);                             // 转化date为日期
            string T1_day = getDate(D);
            float days1 = DateTime.DaysInMonth(D.Year, D.Month);      // 获取日期对应月份的总天数

            DateTime Now = DateTime.Now;
            float days2 = DateTime.DaysInMonth(Now.Year, Now.Month);  // 获取本月的总天数
            int day = FloatToInt(D.Day * days2 / days1);              // 按总天数比例转化为本月对应的某天
            string T2_day = Now.Year + "-" + Now.Month + "-" + day;   // 获取D_day的本月日期 "2016-05-23"

            string monthTime = ToString(D).Replace(T1_day, T2_day);
            return monthTime;                                         // "2016-5-7 12:23:34"
        }

        // 浮点型，按四舍五入转化为整数
        public static int FloatToInt(float n)
        {
            int m = (int)n;
            return n-m<0.5f ? m : m + 1;
        }

        #endregion


        //http://task.joymeng.com/zentaodb.php
        //sql             SELECT * FROM zt_daily WHERE uaccount='admin' AND markday='2016-05-13'  
        //submit          提交                

        // 执行sql语句获取所需信息
        public static String Execute(String sql)
        {
            String data = "";

            string postData = "sql=" + sql + "&submit=提交";
            data = HttpTool.GetHtml("http://" + loginForm.serverIP + "/zentaodb.php", postData, Method.POST);
            if(data.Contains("Notice") && data.Contains("Undefined variable")) return ""; // 未查询到信息

            return data;
        }


        //List<Data_remind> getPreRemindedMessage()

        /// <summary>
        ///  设置ListView列表显示Data_remind信息
        /// </summary>
        public static void setData(ListView list, List<Data_Remind> record)
        {
            string[] heads = { "id", "提醒时间", "标题", "内容", "发送者" };
            int[] width = { 30, 130, 100, 140, 100};

            List<string[]> rows = new List<string[]>();
            foreach(Data_Remind iteam in record)
            {
                string sender = iteam.uaccount.Equals(iteam.urealname) ? iteam.uaccount : (iteam.uaccount + "(" + iteam.urealname + ")");
                string[] row = { iteam.id, iteam.sendTime, iteam.title, iteam.content, sender };
                rows.Add(row);
            }

            setData(list, heads.ToList<string>(), rows, width);    // 在列表中显示任务信息记录
        }

        /// <summary>
        ///  设置ListView列表显示Data_Task信息
        /// </summary>
        public static void setData(ListView list, List<Data_Task> task)
        {
            string[] heads = { "id", "分配时间", "标题", "内容", "发送者", "状态" };
            int[] width = { 30, 130, 100, 140, 100, 50};

            List<string[]> rows = new List<string[]>();
            foreach (Data_Task iteam in task)
            {
                string[] row = { iteam.id, iteam.assignedDate, iteam.name, iteam.desc, iteam.openedBy, iteam.status };
                rows.Add(row);
            }

            setData(list, heads.ToList<string>(), rows, width);    // 在列表中显示任务信息记录
        }

        
        /// <summary>
        ///  设置ListView列表显示Data_Demand信息
        /// </summary>
        public static void setData(ListView list, List<Data_Demand> demand)
        {
            string[] heads = { "id", "分配时间", "标题", "内容", "发送者", "状态" };
            int[] width = { 30, 130, 100, 140, 100, 50};

            List<string[]> rows = new List<string[]>();
            foreach (Data_Demand iteam in demand)
            {
                string[] row = { iteam.id, iteam.assignedDate, iteam.title, iteam.title, iteam.openedBy, iteam.status };
                rows.Add(row);
            }

            setData(list, heads.ToList<string>(), rows, width);    // 在列表中显示任务信息记录
        }

        /// <summary>
        ///  设置ListView列表显示Data_Bug信息
        /// </summary>
        public static void setData(ListView list, List<Data_Bug> Bug)
        {
            string[] heads = { "id", "分配时间", "标题", "内容", "发送者", "接收者", "状态" };
            int[] width = { 30, 130, 100, 140, 100, 100, 50 };

            List<string[]> rows = new List<string[]>();
            foreach (Data_Bug iteam in Bug)
            {
                string[] row = { iteam.id, iteam.assignedDate, iteam.title, iteam.steps, iteam.openedBy, iteam.assignedTo, iteam.status };
                rows.Add(row);
            }

            setData(list, heads.ToList<string>(), rows, width);    // 在列表中显示任务信息记录
        }

        /// <summary>
        ///  设置ListView列表显示Data_Testtask信息
        /// </summary>
        public static void setData(ListView list, List<Data_Testtask> Testtask)
        {
            string[] heads = { "id", "分配时间", "标题", "内容", "发送者", "接收者", "状态" };
            int[] width = { 30, 130, 100, 140, 100, 100, 50 };

            List<string[]> rows = new List<string[]>();
            foreach (Data_Testtask iteam in Testtask)
            {
                string[] row = { iteam.id, iteam.begin, iteam.name, iteam.desc, iteam.build, iteam.owner, iteam.status };
                rows.Add(row);
            }

            setData(list, heads.ToList<string>(), rows, width);    // 在列表中显示任务信息记录
        }

        /// <summary>
        ///  设置ListView列表显示信息
        /// </summary>
        public static void setData(ListView list, List<string> heads, List<string[]> rows, int[] columW)
        {
            list.View = View.Details;
            //list.ShowGroups = true;

            list.HeaderStyle = ColumnHeaderStyle.Nonclickable;
            list.FullRowSelect = true;

            list.BeginUpdate();

            list.Items.Clear();
            list.Groups.Clear();
            list.Columns.Clear();

            // 添加标题
            for (int i = 0; i < heads.Count; i++)
            {
                list.Columns.Add(heads[i], columW[i], HorizontalAlignment.Left);
            }

            // 添加信息到列表
            foreach (string[] row in rows)
            {
                ListViewItem Iteam = new ListViewItem(row);
                list.Items.Add(Iteam);
            }

            list.EndUpdate();
        }






        // 转化为一条字符串
        public static string toString(List<string> Ids)
        {
            string tmp = "";
            foreach (string key in Ids)
            {
                tmp += (tmp.Equals("") ? "" : "#") + key;
            }

            return tmp;
        }

        // 转化为list
        public static List<string> toList(string listStr)
        {
            //List<string> list = new List<string>();
            string[] iteams = listStr.Split('#');
            return iteams.ToList<string>();
        }


        /// <summary>
        /// 定义委托接口处理函数，用于实时处理cmd输出信息
        /// </summary>
        public delegate void ThreadMethod();

        /// <summary>
        /// 在新的线程中执行method逻辑
        /// </summary>
        public static void ThreadRun(ThreadMethod method)
        {
            Thread thread = new Thread(delegate()
            {
                // 允许不同线程间的调用
                Control.CheckForIllegalCrossThreadCalls = false;

                // 执行method逻辑
                if (method != null) method();
            });

            thread.Priority = ThreadPriority.AboveNormal;           // 设置子线程优先级
            Thread.CurrentThread.Priority = ThreadPriority.Highest; // 设置当前线程为最高优先级
            thread.Start();
        }


        # region 文件操作

        /// <summary>
        /// 将文件转换为byte数组
        /// </summary>
        /// <param name="path">文件地址</param>
        /// <returns>转换后的byte数组</returns>
        public static byte[] File2Bytes(string path)
        {
            if (!File.Exists(path)) return new byte[0];

            FileInfo fi = new FileInfo(path);
            byte[] buff = new byte[fi.Length];

            FileStream fs = fi.OpenRead();
            fs.Read(buff, 0, Convert.ToInt32(fs.Length));
            fs.Close();

            return buff;
        }

        /// <summary>
        /// 将byte数组转换为文件并保存到指定地址
        /// </summary>
        /// <param name="buff">byte数组</param>
        /// <param name="savepath">保存地址</param>
        public static void Bytes2File(byte[] buff, string savepath)
        {
            if (File.Exists(savepath)) File.Delete(savepath);

            FileStream fs = new FileStream(savepath, FileMode.CreateNew);
            BinaryWriter bw = new BinaryWriter(fs);
            bw.Write(buff, 0, buff.Length);
            bw.Close();
            fs.Close();
        }

        /// <summary>
        /// 将Image转化为byte数组
        /// </summary>
        public static byte[] Image2Bytes(Image image, ImageFormat imageFormat = null)
        {
            if (imageFormat == null) imageFormat = ImageFormat.Jpeg;

            System.IO.MemoryStream stream = new System.IO.MemoryStream();
            image.Save(stream, imageFormat);
            byte[] bytes = stream.ToArray();

            return bytes;
        }

        /// <summary>
        /// 从byte数组创建Image
        /// </summary>
        public static Image Bytes2Image(byte[] bytes)
        {
            System.IO.MemoryStream stream = new System.IO.MemoryStream();
            stream.Write(bytes, 0, bytes.Length);
            Image image = Image.FromStream(stream);

            return image;
        }

        /// <summary>
        /// 将Image转化为byte数组,使用缓存文件中转
        /// </summary>
        public static byte[] Image2Bytes_tmpFile(Image image, ImageFormat imageFormat = null)
        {
            if (imageFormat == null) imageFormat = ImageFormat.Jpeg;
            String tmpFilePath = AppDomain.CurrentDomain.BaseDirectory + DateTime.Now.Ticks + ".stream";
            image.Save(tmpFilePath, imageFormat);   // 保存图像到文件

            byte[] bytes = File2Bytes(tmpFilePath); // 从文件中获取字节数组
            if (File.Exists(tmpFilePath)) File.Delete(tmpFilePath); //删除文件

            return bytes;
        }

        # endregion



        # region 获取内、外网Ip

        /// <summary>
        /// 获取本地ip地址,优先取内网ip
        /// </summary>
        public static String GetLocalIp()
        {
            try
            {
                String[] Ips = GetLocalIpAddress();

                foreach (String ip in Ips) if (ip.StartsWith("10.80.")) return ip;
                foreach (String ip in Ips) if (ip.Contains(".")) return ip;
            }
            catch (Exception ex) { MessageBox.Show("获取内网ip失败！"); }

            return "127.0.0.1";
        }

        /// <summary>
        /// 获取本地ip地址，多个ip
        /// </summary>
        public static String[] GetLocalIpAddress()
        {
            string hostName = Dns.GetHostName();                    //获取主机名称  
            IPAddress[] addresses = Dns.GetHostAddresses(hostName); //解析主机IP地址  

            string[] IP = new string[addresses.Length];             //转换为字符串形式  
            for (int i = 0; i < addresses.Length; i++) IP[i] = addresses[i].ToString();

            return IP;
        }

        /// <summary>
        /// 获取外网ip地址
        /// </summary>
        public static string GetExtenalIpAddress_0()
        {
            string IP = "未获取到外网ip";
            try
            {
                //从网址中获取本机ip数据  
                System.Net.WebClient client = new System.Net.WebClient();
                client.Encoding = System.Text.Encoding.Default;
                string str = client.DownloadString("http://1111.ip138.com/ic.asp");
                client.Dispose();

                //提取外网ip数据 [218.104.71.178]  
                int i1 = str.IndexOf("["), i2 = str.IndexOf("]");
                IP = str.Substring(i1 + 1, i2 - 1 - i1);
            }
            catch (Exception) { }

            return IP;
        }

        /// <summary>
        /// 获取外网ip地址
        /// </summary>
        public static string GetExtenalIpAddress()
        {
            String url = "http://hijoyusers.joymeng.com:8100/test/getNameByOtherIp";
            string IP = "未获取到外网ip";
            try
            {
                //从网址中获取本机ip数据  
                System.Net.WebClient client = new System.Net.WebClient();
                client.Encoding = System.Text.Encoding.Default;
                string str = client.DownloadString(url);
                client.Dispose();

                if (!str.Equals("")) IP = str;
                else IP = GetExtenalIpAddress_0();
            }
            catch (Exception) { }

            return IP;
        }

        # endregion
    }
}
